/**
 * 
 */
package org.statewalker.core.server;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.Map;

import org.statewalker.core.IState;
import org.statewalker.core.IStateFactory;

public class ClassBasedStateFactory implements IStateFactory {

    private final Constructor<? extends IState> fConstructor;

    private Map<String, String> fProperties;

    private Method fPropertiesSetter;

    public ClassBasedStateFactory(
        Class<? extends IState> cls,
        Map<String, String> properties)
        throws SecurityException,
        NoSuchMethodException {
        fConstructor = cls.getConstructor();
        fPropertiesSetter = getPropertiesSetter(cls);
        fProperties = properties;
        if (fProperties == null) {
            fProperties = Collections.emptyMap();
        }
    }

    private Method getPropertiesSetter(Class<? extends IState> cls) {
        try {
            return cls.getMethod("setProperties", Map.class);
        } catch (NoSuchMethodException e) {
            return null;
        }
    }

    public IState newState(String stateKey) {
        try {
            IState instance = fConstructor.newInstance();
            if (fPropertiesSetter != null) {
                fPropertiesSetter.invoke(instance, fProperties);
            }
            return instance;
        } catch (Exception e) {
            throw new Error(e);
        }
    }

}